<template>
  <div class="container">
    <div class="left">
      <div style="height: 50px; line-height: 50px; padding: 0 20px;">
        <label>监控设备列表</label>
      </div>
      <div class="camera-list">
        <el-input v-model="filterCameraText" placeholder="请输入设备名称" :suffix-icon="Search" style="width: 238px; margin-bottom: 18px; " @input="queryCamera" />

        <el-checkbox-group id="camera-checkbox-group" ref="cameraCheckboxGroup" v-model="checkedCameraIdList" >
          <el-tree-v2
            ref="cameraTreeRef"
            v-loading="cameraTreeLoading"
            style="width: 100%; height: 100%"
            :height="treeHeight"
            :data="cameraTreeData"
            node-key="nodeId" 
            :props="{ value: 'nodeId', label: 'nodeName', children: 'children' }"
            :filter-method="filterCamera"
          >
            <template #default="{ node, data }">
              <template v-if="data.equipmentCameraGroupId">
                <svg-icon icon-class="camera-circle" style="font-size: 18px; position: relative; right: 7px;;" />
                <span style="display: inline-block; width: calc(100% - 90px); height: 26px; line-height: 26px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;" >
                  {{ data.nodeName }} 
                </span>
              </template>
              <el-checkbox v-else :value="data.nodeId" :disabled="data.deviceStatus=='OFFLINE'" @change="(flag)=> { cameraCheckChange(data.nodeId, flag) }"> 
                <span v-if="data.deviceStatus=='OFFLINE'" style="color: rgb(200 90 90);">（离线）</span> 
                <span>{{ node.label }}</span>
              </el-checkbox>
            </template>
          </el-tree-v2>
        </el-checkbox-group>
      </div>
    </div>
    <div id="right" class="right">
      <div style="height: 50px; line-height: 50px; padding: 0 20px; position: relative; display: flex;">
        <div style="width: 140px; height: 50px; display: flex; justify-content: space-around; align-items: center;">
          <div class="camera-layout-item" @click="changeLayout(1)">
            <svg-icon icon-class="one-grid" style="width: 30px; height: 30px;" :style="{ color: gridColNum==1 ? '#3751FE' : '#BEDAFF' }" />
          </div>
          <div class="camera-layout-item" @click="changeLayout(4)">
            <svg-icon icon-class="four-grid" style="width: 30px; height: 30px;" :style="{ color: gridColNum==2 ? '#3751FE' : '#BEDAFF' }" />
          </div>
          <!-- <div class="camera-layout-item" @click="changeLayout(9)">
            <svg-icon icon-class="nine-grid" style="width: 30px; height: 30px;" :style="{ color: gridColNum==3 ? '#3751FE' : '#BEDAFF' }" />
          </div> -->
        </div>

        <div style="height: 50px; line-height: 50px; padding: 0 20px; position: absolute; right: 140px; display: flex; align-items: center;">
          <p style="width: 72px;">预案场景</p>
          <el-select v-model="cameraMonitorPlanId" v-loading="cameraMonitorPlanLoading" placeholder="请选择" style="width: 180px;" clearable @change="cameraMonitorPlanChange">
            <el-option v-for="item in cameraMonitorPlanList" :key="item.cameraMonitorPlanId" :label="item.monitorPlanName" :value="item.cameraMonitorPlanId"></el-option>
          </el-select>
        </div>

        <div style="height: 50px; line-height: 48px; padding: 0 20px; position: absolute; right: 30px;">
          <el-button type="primary" size="default" @click="openEventReport()">事件上报</el-button>
        </div>
      </div>

      <grid-layout v-model:layout="gridLayoutData" :col-num="gridColNum" :row-height="gridRowHeight" :is-draggable="false" :is-resizable="false" :is-mirrored="false" :vertical-compact="true" :margin="gridMargin" :use-css-transforms="false" >
        <grid-item v-for="item in gridLayoutData" :key="item.i" v-loading="item.loading" :x="item.x" :y="item.y" :w="item.w" :h="item.h" :i="item.i">
          <div v-if="item.equipmentId==null && item.loading==false">请选择摄像机</div>
          <VideoEasyPlayer v-if="item.equipmentId" :id="item.equipmentId" :url="item.url" :show-loading="item.loading" :show-video-control="true" @open-camera-control="openCameraControl(item)"/>
        </grid-item>
      </grid-layout>
    </div>

    <!-- 全屏 -->
    <el-dialog v-model="showCameraControl" title="设备详情" width="1000" append-to-body destroy-on-close>
      <camera-control :camera-data="selectedCamera" />
    </el-dialog>

    <!-- 事件上报 -->
    <el-dialog v-model="showEventReport" title="事件上报" width="600" append-to-body destroy-on-close>
      <event-report :event-source="2" @close="showEventReport=false" />
    </el-dialog>
  </div>
</template>

<script setup  lang="ts">
import EventReport from './components/EventReport.vue';
import CameraControl from '@/views/security/video-monitor/real-time-monitor/components/CameraControl.vue';
import { listcameraMonitorPlan } from '@/api/security/video-monitor/camera-monitor-plan';
import VideoEasyPlayer from '@/components/VideoEasyPlayer/index.vue';
import request from '@/utils/request';
import { ElTree } from 'element-plus';
import { Calendar, Search } from '@element-plus/icons-vue'
import type { TreeNodeData } from 'element-plus/es/components/tree-v2/src/types'
import { tr } from 'element-plus/es/locale';

const { proxy } = getCurrentInstance() as ComponentInternalInstance;

const filterCameraText = ref();
const currLayoutNum = ref(4);
const leftDomHeight = ref();
const gridMargin = ref([10, 10]);
const showEventReport = ref(false);
const selectedCamera = ref<any>({})
const cameraMonitorPlanId = ref()
const cameraMonitorPlanList = ref([])
const cameraMonitorPlanLoading = ref(false)
const cameraTreeRef = ref<any>()
const showCameraControl = ref(false)
const cameraTreeLoading = ref(false)
interface Tree{ label: string, children?: Tree[] }
const treeHeight = ref(0)

/**
 * 获取监控预案
 */
const getCameraMonitorPlan = ()=> {
  cameraMonitorPlanLoading.value = true
  listcameraMonitorPlan().then((res)=> {
    cameraMonitorPlanList.value = res.rows
  }).finally(()=> { cameraMonitorPlanLoading.value = false })
}

/**
 * 监控预案选择
 */
const cameraMonitorPlanChange = async (id)=> {
  if (id) {
    const loadingInstance = ElLoading.service({ fullscreen: true, text: '正在切换, 请稍候...' })
    request({
      url: '/camera/camera-monitor-plan-camera/list',
      method: 'get',
      params: { planId: id }
    }).then((res) => {
      console.log('获取监控预案设备：', res)

      //  清空已选摄像机
      gridLayoutData.value.forEach(item => {
        item.equipmentId = null;
        item.url = null;
        item.loading = false
      });

      checkedCameraIdList.value = res.rows?.map((item: any) =>{ return item.cameraId })

      //  展开所有节点
      // nextTick(()=> {
      //   cameraTreeRef.value.setExpandedKeys(cameraTreeData.value.map(item=> { return item.nodeId }));
      // })

      nextTick(()=> {
        playVideo(null, null)
      })
    }).finally(()=> { loadingInstance.close() })
  } else {
    //  初始化视频布局
    changeLayout(currLayoutNum.value)
    //  选择默认栅格数量摄像机
    playVideo(null, null)
  }
}

/**
 * 打开摄像机控制页面
 */
const openCameraControl = (item) => {
  selectedCamera.value = item
  showCameraControl.value = true;
}

/**
 * 查询摄像头信息列表
 * */
const cameraTreeData = ref([]);
const cameraCheckboxGroup = ref();
const getCameraTreeList = async () => {
  cameraTreeLoading.value = true
  let cameraTreeRes = await request({
    url: '/equipment/equipment-camera-group/tree',
    method: 'get'
  }).finally(() => { cameraTreeLoading.value = false })

  console.log('获取摄像机：', cameraTreeRes)
  
  cameraTreeData.value = cameraTreeRes.data;

  //  展开所有节点
  await nextTick(()=> {
    cameraTreeRef.value?.setExpandedKeys(cameraTreeData.value.map(item=> { return item.nodeId }));
  })
}

/**
 * 过滤摄像头
 */
const queryCamera = (query: string) => {
  cameraTreeRef.value!.filter(query)
}

/**
 * 过滤摄像头
 */
const filterCamera = (query: string, data: TreeNodeData) => {
  return data.nodeName!.includes(query)
}

/**
 * 选择指定数量摄像机
 * */
const cameraList = ref([]);
const selectCameraByNum = async (num: number) => {
  console.log('选择指定数量摄像机：', num)

  cameraList.value = []

  //  选中栅格数量的设备
  cameraTreeData.value.forEach((item) => {
    if (item.children && item.children.length > 0) {
      cameraList.value = cameraList.value.concat(item.children)
    }
  })

  //  选择指定数量摄像机
  checkedCameraIdList.value = cameraList.value.filter((item1, index1)=> { return index1 < num && item1.deviceStatus == 'ONLINE'; }).map((item2) => { return item2.nodeId })
}

/**
 * 切换视频布局
 */
const gridColNum = ref(2);
const gridRowHeight = ref(0);
const gridLayoutData = ref([])
const changeLayout = (value: number) => {
  currLayoutNum.value = value

  nextTick(()=> {
    if (value == 1) {
      gridColNum.value = 1
      gridRowHeight.value = leftDomHeight.value - 50 - 14
      gridLayoutData.value = [{ 'x': 0, 'y': 0, 'w': 1, 'h': 1, 'i': '1', 'loading': false }]
    }
    if (value == 4) {
      gridColNum.value = 2
      gridRowHeight.value = (leftDomHeight.value - 50) / 2 - 14
      gridLayoutData.value = [
        { 'x': 0, 'y': 0, 'w': 1, 'h': 1, 'i': '1', 'loading': false },
        { 'x': 1, 'y': 0, 'w': 1, 'h': 1, 'i': '2', 'loading': false },
        { 'x': 0, 'y': 1, 'w': 1, 'h': 1, 'i': '3', 'loading': false },
        { 'x': 1, 'y': 1, 'w': 1, 'h': 1, 'i': '4', 'loading': false }
      ]
    }
    if (value == 9) {
      gridColNum.value = 3
      gridRowHeight.value = (leftDomHeight.value - 50) / 3 - 14
      gridLayoutData.value = [
        { 'x': 0, 'y': 0, 'w': 1, 'h': 1, 'i': '1', 'loading': false },
        { 'x': 1, 'y': 0, 'w': 1, 'h': 1, 'i': '2', 'loading': false },
        { 'x': 2, 'y': 0, 'w': 1, 'h': 1, 'i': '3', 'loading': false },
        { 'x': 0, 'y': 1, 'w': 1, 'h': 1, 'i': '4', 'loading': false },
        { 'x': 1, 'y': 1, 'w': 1, 'h': 1, 'i': '5', 'loading': false },
        { 'x': 2, 'y': 1, 'w': 1, 'h': 1, 'i': '6', 'loading': false },
        { 'x': 0, 'y': 2, 'w': 1, 'h': 1, 'i': '7', 'loading': false },
        { 'x': 1, 'y': 2, 'w': 1, 'h': 1, 'i': '8', 'loading': false },
        { 'x': 2, 'y': 2, 'w': 1, 'h': 1, 'i': '9', 'loading': false }
      ]
    }

    //  选择指定数量摄像机
    selectCameraByNum(value)
  })

  nextTick(()=> {
    playVideo(null, null)
  })
}

/**
 * 摄像机复选框点击
 */
const checkedCameraIdList = ref([]);
const cameraCheckChange = (cameraId: any, flag: any) => {
  console.log('点击的摄像机：', cameraId, flag)
  console.log('已选中的摄像机：', checkedCameraIdList)

  // if (checkedCameraIdList.value.length > currLayoutNum.value) {
  //   proxy.$modal.msgWarning('当前只能选择' + currLayoutNum.value + '个摄像机')
  //
  //   //  取消选择
  //   checkedCameraIdList.value.splice(checkedCameraIdList.value.indexOf(cameraId), 1)
  // } else {
  let checkedCamera = cameraList.value.find((item) => { return item.nodeId == cameraId })
  let checkedCameraIndex = checkedCameraIdList.value.indexOf(cameraId)

  console.log('选择的摄像机：', checkedCamera)
  console.log('选中的摄像机索引：', checkedCameraIndex)

  playVideo(checkedCamera, checkedCameraIndex)
  // }
}

/**
 * 播放视频
 */
const playVideo = (node, cameraIndex) => {
  console.log('播放视频：', node, cameraIndex)

  //  获取当前选择的摄像机
  let equipmentList = []
  if (cameraList.value.length > 0) {
    equipmentList = cameraList.value.filter((item)=> { return checkedCameraIdList.value.includes(item.equipmentId) })
  }
  console.log('获取当前选择的摄像机：', equipmentList)

  if (cameraIndex == -1) {
    //  删除指定位置的视频
    gridLayoutData.value.forEach(item => {
      if (cameraIndex == -1 && item.equipmentId == node.equipmentId) {
        item.equipmentId = null; 
        item.url = null; 
        item.loading = false 
      }
    });
  } else {
    for (let gridItem of gridLayoutData.value) {
      //  指定位置播放视频
      if (node != null) {
        if (gridItem.equipmentId == null) {
          getVideoUrl(node, gridItem)

          return
        }
      } else {
        //  播放栅格数量的视频
        if (Number(gridItem.i) <= equipmentList.length) {
          getVideoUrl(equipmentList[Number(gridItem.i) - 1], gridItem)
        }
      }
    }
  }
}

/**
 * 获取视频地址
 */
const getVideoUrl = (node: any, gridItem: any) => {
  gridItem.loading = true
  request({
    url: '/equipment/equipment-info/get-video-url/' + node.equipmentId,
    method: 'get',
    params: { playType: 0, playProtocol: 0 }
  }).then((videoRes)=> {
    console.log('获取视频地址：', videoRes)

    if (videoRes.data && videoRes.data.media_url) {
      gridItem.equipmentId = node.equipmentId
      gridItem.url = JSON.parse(videoRes.data.media_url).wan
      gridItem.equipmentId = node.equipmentId
      gridItem.equipmentName = node.equipmentName

      console.log('栅格信息：', gridItem)
    }
  }).finally(()=> { gridItem.loading = false })
}

/**
 * 打开事件上报
 */
const openEventReport = ()=> {
  showEventReport.value = true
}

onMounted(async () => {
  //  获取左侧元素高度
  const leftElement = document.getElementById('right');
  leftDomHeight.value = leftElement.clientHeight

  // 设置树高度
  const cameraCheckboxGroupElement = document.getElementById('camera-checkbox-group');
  treeHeight.value = cameraCheckboxGroupElement.clientHeight

  //  获取摄像机
  await getCameraTreeList();

  //  初始化视频布局
  changeLayout(currLayoutNum.value)

  //  获取监控预案
  getCameraMonitorPlan()
});
</script>
<style lang="scss" scoped>
  .container {
    display: flex;
    flex-direction: row !important;
    position: relative;
    height: 100%;
  }
    :deep(.el-card__header) {
        height: 60px;
    }
    :deep(.el-card__body) {
        height: calc(100% - 60px);
    }
    :deep(.pagination-container) {
        margin-top: 0;
    }
    :deep(.camera-scene-tabs .el-tabs__nav-scroll) {
      display: flex;
      justify-content: center;
    }
    :deep(.camera-scene-tabs > .el-tabs__content) {
      padding: 32px;
    }
    .left {
      height: 100%;
      width: 260px;
      position: absolute;
      left: 0;
      border: 1px solid #DCDFE6;
    }
    .right {
      height: 100%;
      width: calc(100% - 270px);
      border: 1px solid #DCDFE6;
      position: absolute;
      right: 0;
    }
    .camera-list {
      height: calc(100% - 50px);
      padding: 0 10px;
      display: flex;
      flex-direction: column;
    }
    .camera-control {
      height: 200px;
      display: flex;
      flex-wrap: wrap;
      justify-content: space-around;
      align-items: center;
      border: 1px solid #0b0a0a;
    }
    .camera-layout-item {
      display: flex;
      justify-content: center;
      align-items: center;
      width: 40px;
      height: 40px;
      cursor: pointer;
    }
     .vue-grid-layout {
       height: calc(100% - 50px) !important;
       background: #ffffff;
       .vue-grid-item {
         display: flex;
         justify-content: center;
         align-items: center;
         background-color: #ccc;
         border: 1px solid #ccc;
       }
     }

    .vue-grid-item:not(.vue-grid-placeholder) {
      background: #eeecec;
      border: 1px solid #ccc;
    }

    .vue-grid-item .resizing {
      opacity: 0.9;
    }

    .vue-grid-item .static {
      background: #cce;
    }
    .vue-grid-item .text {
      font-size: 24px;
      text-align: center;
      position: absolute;
      top: 0;
      bottom: 0;
      left: 0;
      right: 0;
      margin: auto;
      height: 100%;
      width: 100%;
    }
    .vue-grid-item .no-drag {
      height: 100%;
      width: 100%;
    }
    .vue-grid-item .minMax {
      font-size: 12px;
    }
    .vue-grid-item .add {
      cursor: pointer;
    }
    .vue-draggable-handle {
      position: absolute;
      width: 20px;
      height: 20px;
      top: 0;
      left: 0;
      background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'><circle cx='5' cy='5' r='5' fill='#999999'/></svg>") no-repeat;
      background-position: bottom right;
      padding: 0 8px 8px 0;
      background-repeat: no-repeat;
      background-origin: content-box;
      box-sizing: border-box;
      cursor: pointer;
    }
    :deep(.el-tree-node__expand-icon) {
      left: 200px;
      font-size: 14px;
      color: #3c3c3c;
      transform: rotate(180deg);
    }
    :deep(.el-tree-node__expand-icon.expanded) {
      transform: rotate(90deg);
    }
    :deep(#camera-checkbox-group) {
      flex: 1;
    }
    :deep(#camera-checkbox-group .el-checkbox__inner) {
      border-radius: 50%;
    }
</style>
